home *** CD-ROM | disk | FTP | other *** search
/ Mac Magazin/MacEasy 19 / Mac Magazin and MacEasy Magazine CD - Issue 19.iso / Utilities / uae-0.4 / Source Code / mac.c < prev    next >
Text File  |  1996-02-13  |  14KB  |  602 lines

  1.  /* 
  2.   * UAE - The Un*x Amiga Emulator
  3.   * 
  4.   * Mac port specific stuff
  5.   * 
  6.   * (c) 1996 Ernesto Corvi
  7.   */
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <QDOffscreen.h>
  13. #include <Palettes.h>
  14. #include <Profiler.h>
  15.  
  16. #include "mackbd.h"
  17. #include "config.h"
  18. #include "amiga.h"
  19. #include "options.h"
  20. #include "memory.h"
  21. #include "custom.h"
  22. #include "newcpu.h"
  23. #include "xwin.h"
  24. #include "keyboard.h"
  25. #include "keybuf.h"
  26.  
  27. #define kQuitError 128
  28.  
  29. extern bool left, right, top, bot, but;
  30.  
  31. KeyMap keys,keysold;
  32. GDHandle        curDevice;
  33. int        oldDepth=0;
  34. static int screen;
  35. Boolean    RM=false,Joy=false;
  36. WindowPtr mywin;
  37. short    gOldMBarHeight;
  38. RgnHandle gMBarRgn;
  39. static int bitdepth;
  40. KeyMap theKeys;
  41.  
  42. unsigned long refresh;
  43. char *xlinebuffer;
  44. unsigned int *obuff;
  45. long int xcolors[4096];
  46.  
  47.  /* Keyboard and mouse */
  48.  
  49. static bool keystate[256];
  50.  
  51. bool buttonstate[3];
  52. int lastmx, lastmy;
  53. bool newmousecounters;
  54. static bool inwindow;
  55.  
  56. int GetRawCode (long set0, long set1, long set2, long set3);
  57.  
  58. static inline unsigned long doMask(int p, int bits, int shift)
  59. {
  60.     /* p is a value from 0 to 15 (Amiga color value)
  61.      * scale to 0..255, shift to align msb with mask, and apply mask */
  62.  
  63.     unsigned long val = p * 0x11111111UL;
  64.     val >>= (32 - bits);
  65.     val <<= shift;
  66.  
  67.     return val;
  68. }
  69.  
  70. static void InitXColors(void)
  71. {
  72.     int n=16;
  73.     int red_bits = 5;
  74.     int green_bits = 5;
  75.     int blue_bits = 5;
  76.     int red_shift = 10;
  77.     int green_shift = 5;
  78.     int blue_shift = 0;
  79.     int i=0;
  80.     int r,g,b;
  81.     
  82.     for(i = 0; i < 4096; i++) {
  83.     r = i >> 8;
  84.     g = (i >> 4) & 0xF;
  85.     b = i & 0xF;
  86.     xcolors[i] = (doMask(r, red_bits, red_shift) 
  87.               | doMask(g, green_bits, green_shift) 
  88.               | doMask(b, blue_bits, blue_shift));
  89.     }
  90. }
  91.  
  92. static void InitToolbox(void)
  93. {
  94.     InitGraf (&qd.thePort);
  95.     InitFonts ();
  96.     FlushEvents (everyEvent,0);
  97.     InitWindows ();
  98.     InitMenus ();
  99.     TEInit ();
  100.     InitDialogs (nil);
  101.     InitCursor ();
  102. }
  103.  
  104. static void HideMenuBar(void)
  105. {
  106.     Rect mBarRect;
  107.  
  108.     /* GET RID OF THE MENU BAR */
  109.                     
  110.     gOldMBarHeight = GetMBarHeight();
  111.     /* make the Menu Bar's height zero */
  112.     LMSetMBarHeight(0);
  113.     SetRect(&mBarRect, qd.screenBits.bounds.left, qd.screenBits.bounds.top,
  114.         qd.screenBits.bounds.right, qd.screenBits.bounds.top + gOldMBarHeight);
  115.     gMBarRgn = NewRgn();
  116.     RectRgn(gMBarRgn, &mBarRect);
  117.     UnionRgn(LMGetGrayRgn(), gMBarRgn, LMGetGrayRgn());    /* tell the desktop it covers the menu bar */
  118.  
  119.     PaintOne(nil, gMBarRgn); /* redraw desktop */
  120. }
  121.  
  122. static void ShowMenuBar(void)
  123. {
  124.     LMSetMBarHeight(gOldMBarHeight); /* make the menu bar's height normal */
  125.     DiffRgn(LMGetGrayRgn(), gMBarRgn, LMGetGrayRgn()); /* remove the menu bar from the desktop */
  126.     DisposeRgn(gMBarRgn);
  127. }
  128.  
  129. void graphics_init()
  130. {    int i;
  131.     long p1;
  132.     long tmp;
  133.  
  134.     Rect    windowRectangle={0,0,480,640};
  135.     InitToolbox();
  136.     
  137.     if (CheckForSetup()) ExitToShell();
  138.     
  139.     HideMenuBar();
  140.     mywin = NewCWindow(nil, &windowRectangle, "\pUAE", true, 2, (WindowPtr)-1L, false, 0);
  141.     SetPort(mywin);
  142.  
  143.     PaintRect(&qd.screenBits.bounds);
  144.     
  145.     xlinebuffer = (char *)malloc (3200);
  146.     InitXColors();
  147.     buttonstate[0] = buttonstate[1] = buttonstate[2] = false;
  148.     for(i=0; i<256; i++) keystate[i] = false;
  149.     
  150.     lastmx = lastmy = 0; newmousecounters = false; inwindow = false;
  151.     
  152.     obuff=(unsigned int *)NewPtrClear(481*1280);
  153.     {
  154.         for(p1=0;p1 < (480*1280);p1++)
  155.             *obuff=-1;
  156.     }
  157.     
  158.     HideCursor();
  159.     refresh=TickCount();
  160.     
  161. /*    tmp=ProfilerInit(collectDetailed,bestTimeBase,200,10); */
  162. }
  163.  
  164. void graphics_leave()
  165. {
  166. /*    ProfilerDump((unsigned char *)"\pmyProf");
  167.     ProfilerTerm();
  168.  */
  169.     DisposeWindow(mywin);
  170.     ShowCursor();
  171.     if (oldDepth != 0) SetDepth(curDevice,oldDepth,0,0);
  172.     ShowMenuBar();
  173.     FlushEvents (everyEvent,0);
  174.     ExitToShell();
  175. }
  176.  
  177. static bool next_line_double;
  178. static int next_line_pos = 0;
  179.  
  180. void flush_screen ()
  181. {  
  182.     GrafPtr oldPort;
  183.     short    y,x,daColor=0;
  184.     RGBColor    daColorRGB;
  185.     unsigned char *winbaseaddr;
  186.     double *src,*dest;
  187.     unsigned long winrowbytes;
  188.     PixMapHandle    ph;
  189.     
  190.     if (TickCount() < refresh + 4) return;
  191.     GetPort(&oldPort);
  192.     SetPort(mywin);
  193.    
  194.     ph=GetGWorldPixMap((CGrafPort *) mywin);
  195.     LockPixels(ph);
  196.     winbaseaddr=( unsigned char *) GetPixBaseAddr(ph);
  197.     winrowbytes=(*ph)->rowBytes & 0x3FFF;
  198.     winbaseaddr-=((**ph).bounds.left);
  199.     winbaseaddr-=((**ph).bounds.top*winrowbytes);
  200.     dest=(double *)winbaseaddr;
  201.     src=(double *)obuff;
  202.     
  203.     for (y=1; y< 480; y++)
  204.     {
  205.     for (x=0;x < 160;x++)
  206.     {  
  207.         *dest++ = *src++;
  208.     }
  209.     dest=(double *)(winbaseaddr+(y*winrowbytes));
  210.     }
  211.     UnlockPixels(ph);
  212.     SetPort(oldPort);
  213.  
  214. }
  215.  
  216. void prepare_line (int y, bool need_double)
  217. {
  218.     next_line_double = need_double;
  219.     next_line_pos = y;
  220. }
  221.  
  222. void flush_line()
  223. {
  224.     short i;
  225.     char *dst,*src;
  226.     double *dst1,*src1;
  227.      
  228.     if ((next_line_pos < 508) && (next_line_pos > 28))
  229.     {    
  230.     dst=(char *)obuff+((next_line_pos-28)*1280);
  231.     src=(char *)xlinebuffer+292;
  232.     BlockMove(src,dst,1280);  
  233.     }
  234.     if (next_line_double)
  235.     {    
  236.     if ((next_line_pos+1 < 508) && (next_line_pos+1 > 28))
  237.     {    
  238.         dst1=(double *)obuff+((next_line_pos+1-28)*160);
  239.         src1=(double *)obuff+((next_line_pos-28)*160);
  240.         for (i=0;i < 160;i++)
  241.         {  
  242.         *dst1++=*src1++;
  243.         }
  244.     }
  245.     }
  246. }
  247.  
  248. /* Decode KeySyms. This function knows about all keys that are common 
  249.  * between different keyboard languages.
  250.  */
  251. static int kc_decode (long ks)
  252. {    
  253.     switch (ks)
  254.     {
  255.      case kAKeyMap: return AK_A;
  256.      case kBKeyMap: return AK_B;
  257.      case kCKeyMap: return AK_C;
  258.      case kDKeyMap: return AK_D;
  259.      case kEKeyMap: return AK_E;
  260.      case kFKeyMap: return AK_F;
  261.      case kGKeyMap: return AK_G;
  262.      case kHKeyMap: return AK_H;
  263.      case kIKeyMap: return AK_I;
  264.      case kJKeyMap: return AK_J;
  265.      case kKKeyMap: return AK_K;
  266.      case kLKeyMap: return AK_L;
  267.      case kMKeyMap: return AK_M;
  268.      case kNKeyMap: return AK_N;
  269.      case kOKeyMap: return AK_O;
  270.      case kPKeyMap: return AK_P;
  271.      case kQKeyMap: return AK_Q;
  272.      case kRKeyMap: return AK_R;
  273.      case kSKeyMap: return AK_S;
  274.      case kTKeyMap: return AK_T;
  275.      case kUKeyMap: return AK_U;
  276.      case kVKeyMap: return AK_V;
  277.      case kWKeyMap: return AK_W;
  278.      case kXKeyMap: return AK_X;
  279.      
  280.      case k0KeyMap: return AK_0;
  281.      case k1KeyMap: return AK_1;
  282.      case k2KeyMap: return AK_2;
  283.      case k3KeyMap: return AK_3;
  284.      case k4KeyMap: return AK_4;
  285.      case k5KeyMap: return AK_5;
  286.      case k6KeyMap: return AK_6;
  287.      case k7KeyMap: return AK_7;
  288.      case k8KeyMap: return AK_8;
  289.      case k9KeyMap: return AK_9;
  290.      
  291.      case kKP0KeyMap: return AK_NP0;
  292.      case kKP1KeyMap: return AK_NP1;
  293.      case kKP2KeyMap: return AK_NP2;
  294.      case kKP3KeyMap: return AK_NP3;
  295.      case kKP4KeyMap: return AK_NP4;
  296.      case kKP5KeyMap: return AK_NP5;
  297.      case kKP6KeyMap: return AK_NP6;
  298.      case kKP7KeyMap: return AK_NP7;
  299.      case kKP8KeyMap: return AK_NP8;
  300.      case kKP9KeyMap: return AK_NP9;
  301.     
  302.      case kF1KeyMap: return AK_F1;
  303.      case kF2KeyMap: return AK_F2;
  304.      case kF3KeyMap: return AK_F3;
  305.      case kF4KeyMap: return AK_F4;
  306.      case kF5KeyMap: return AK_F5;
  307.      case kF6KeyMap: return AK_F6;
  308.      case kF7KeyMap: return AK_F7;
  309.      case kF8KeyMap: return AK_F8;
  310.      case kF9KeyMap: return AK_F9;
  311.      case kF10KeyMap: return AK_F10;
  312.     
  313.      case kBackSpaceKeyMap: return AK_BS;
  314.      case kTabKeyMap: return AK_TAB;
  315.      case kReturnKeyMap: return AK_RET;
  316.      case kEscapeKeyMap: return AK_ESC;
  317.      
  318.      case kSpaceBarMap: if (Joy) return -1; else return AK_SPC;
  319.      
  320.      case kUpArrowKeyMap: if (Joy) return -1; else return AK_UP;
  321.      case kDownArrowKeyMap: if (Joy) return -1; else return AK_DN;
  322.      case kLeftArrowKeyMap: if (Joy) return -1; else return AK_LF;
  323.      case kRightArrowKeyMap: if (Joy) return -1; else return AK_RT;
  324.     
  325.      case kF11KeyMap: graphics_leave();
  326.      case kF12KeyMap: { Joy=!Joy; SysBeep(0); return -1; }
  327.  
  328.      case kPgUpKeyMap: return AK_RAMI;
  329.      case kPgDnKeyMap: return AK_LAMI;
  330.      case kBackSlash: return AK_BACKSLASH;
  331.     }
  332.     return -1;
  333. }
  334.  
  335. static int decode_us(long ks)
  336. {
  337.     switch(ks) {
  338.     /* US specific */
  339.  
  340.      case kYKeyMap: return AK_Y;
  341.      case kZKeyMap: return AK_Z;
  342.      case kLBracketKeyMap: return AK_LBRACKET;
  343.      case kRBracketKeyMap: return AK_RBRACKET;
  344.      case kCommaKeyMap: return AK_COMMA;
  345.      case kPeriodKeyMap: return AK_PERIOD;
  346.      case kSlashKeyMap: return AK_SLASH;
  347.      case kSemiColonKeyMap: return AK_SEMICOLON;
  348.      case kMinusKeyMap: return AK_MINUS;
  349.      case kEqualKeyMap: return AK_EQUAL;
  350.      case kQuoteKeyMap: return AK_QUOTE;
  351.     }
  352.  
  353.     return -1;
  354. }
  355.  
  356. static int decode_de(long ks)
  357. {
  358.     switch(ks) {
  359. /* DE specific
  360.      case XK_Y: case XK_y: return AK_Z;
  361.      case XK_Z: case XK_z: return AK_Y;
  362.      case XK_Odiaeresis: case XK_odiaeresis: return AK_SEMICOLON;
  363.      case XK_Adiaeresis: case XK_adiaeresis: return AK_QUOTE;
  364.      case XK_Udiaeresis: case XK_udiaeresis: return AK_LBRACKET;
  365.      case XK_plus: case XK_asterisk: return AK_RBRACKET;
  366.      case XK_comma: return AK_COMMA;
  367.      case XK_period: return AK_PERIOD;
  368.      case XK_less: case XK_greater: return AK_LTGT;
  369.      case XK_numbersign: return AK_NUMBERSIGN;
  370.      case XK_ssharp: return AK_MINUS;
  371.      case XK_apostrophe: return AK_EQUAL;
  372.      case XK_asciicircum: return AK_00;
  373.      case XK_minus: return AK_SLASH;        
  374. */
  375.     }
  376.  
  377.     return -1;
  378. }
  379.  
  380. static int keycode2amiga(long code)
  381. {
  382.     long ks;
  383.     int as;
  384.     
  385.     ks = (code & keyCodeMask) >> 8;
  386.     as = kc_decode (ks);
  387.     
  388.     if (as == -1) {        
  389.     switch(keyboard_lang) {
  390.      case KBD_LANG_US:
  391.         as = decode_us(ks);
  392.         break;
  393.         
  394.      case KBD_LANG_DE:
  395.         as = decode_de(ks);
  396.         break;
  397.         
  398.      default:
  399.         as = -1;
  400.         break;
  401.     }
  402.     }
  403.     if(-1 != as)
  404.     return as;
  405.     return -1;
  406. }
  407.  
  408. void handle_events()
  409. {
  410.     Boolean repeat;
  411.     Boolean itHappened;
  412.     Point   mpos;
  413.     EventRecord event;
  414.     int kc,i,count;
  415.     
  416.     SetEventMask(-1);
  417.     SelectWindow(mywin);
  418.     HideCursor();
  419.     
  420.     GetKeys(keys);
  421.     if (BitTst(&keys, kCommandRawKey))
  422.     RM=true;
  423.     else
  424.     RM=false;
  425.     
  426.     if (BitTst(&keys, kShiftRawKey))
  427.     {    
  428.     if (!keystate[AK_LSH]) {
  429.         keystate[AK_LSH] = true;
  430.         record_key (AK_LSH << 1);
  431.         goto label1;
  432.     }
  433.     } else {
  434.     if (keystate[AK_LSH]) {
  435.         keystate[AK_LSH] = false;
  436.         record_key ((AK_LSH << 1) | 1);
  437.         goto label1;
  438.     }
  439.     }
  440.     if (BitTst(&keys, kControlRawKey))
  441.     {    
  442.     if (!keystate[AK_CTRL]) {
  443.         keystate[AK_CTRL] = true;
  444.         record_key (AK_CTRL << 1);
  445.         goto label1;
  446.     }
  447.     } else {    
  448.     if (keystate[AK_CTRL]) {
  449.         keystate[AK_CTRL] = false;
  450.         record_key ((AK_CTRL << 1) | 1);
  451.         goto label1;
  452.     }
  453.     }
  454.     if (BitTst(&keys, kOptionRawKey))
  455.     {    
  456.     if (!keystate[AK_LALT]) {
  457.         keystate[AK_LALT] = true;
  458.         record_key (AK_LALT << 1);
  459.         goto label1;
  460.     }
  461.     } else {
  462.     if (keystate[AK_LALT]) {
  463.         keystate[AK_LALT] = false;
  464.         record_key ((AK_LALT << 1) | 1);
  465.         goto label1;
  466.     }
  467.     }
  468.     do {
  469.     repeat = false;
  470.     newmousecounters = false;
  471.     itHappened=WaitNextEvent(-1,&event,0L,0L);
  472.  
  473.     switch(event.what) {
  474.      case keyDown:
  475.      case autoKey: {    
  476.          int kc = keycode2amiga(event.message);
  477.          if (kc == -1) break;
  478.          if (RM == true && kc == AK_Q) graphics_leave();
  479.          switch (kc) {
  480.           case AK_mousestuff:
  481. #if 0
  482.              if (keystate[AK_CTRL])
  483.              mousesetup();
  484.               else 
  485. #endif
  486.              togglemouse();
  487.               break;
  488.  
  489.           case AK_inhibit:
  490.               inhibit_frame ^= 1;
  491.               break;
  492.  
  493.           default:
  494.               if (!keystate[kc]) {
  495.              keystate[kc] = true;
  496.              record_key (kc << 1);
  497.          }
  498.          break;
  499.          }
  500.          break;
  501.      }
  502.      case keyUp: {         
  503.          if (Joy) break;
  504.          kc = keycode2amiga(event.message);
  505.          if (kc == -1) break;
  506.          keystate[kc] = false;
  507.          record_key ((kc << 1) | 1);
  508.          break;
  509.      }
  510.      case mouseDown:
  511.         if (RM == true) buttonstate[2] = true;
  512.         else buttonstate[0] = true;
  513.         break;
  514.      case mouseUp:
  515.         buttonstate[0] = false;
  516.         buttonstate[2] = false;
  517.         break;
  518.     }
  519.     GetMouse(&mpos);
  520.     if (mpos.h != lastmx) { lastmx=mpos.h; repeat = true; }
  521.     if (mpos.v != lastmy) { lastmy=mpos.v; repeat = true; }
  522.     } while (repeat);
  523.     
  524. label1:
  525.     /* "Affengriff" */
  526.     if(keystate[AK_CTRL] && keystate[AK_LAMI] && keystate[AK_RAMI])
  527.         MC68000_reset();
  528. }
  529.  
  530. bool debuggable()
  531. {
  532.     return true;
  533. }
  534.  
  535. bool needmousehack()
  536. {
  537.     return true;
  538. }
  539.  
  540. void LED(int on)
  541. {
  542. }
  543.  
  544. void parse_cmdline ()
  545. {
  546.     /* No commandline on the Mac. Implemented on Menus soon!*/
  547. }
  548.  
  549. // Check Minimal System Configuration and Setup
  550. static Boolean CheckForSetup (void)
  551. {    Boolean            retvalue=FALSE;
  552.     SysEnvRec        env;
  553.     
  554.     SysEnvirons( 2, &env );
  555.     
  556.     if ( env.systemVersion < 0x0700 )
  557.     {    ParamAString("\pUAE requires System 7 or later!");
  558.         DisplayError(kQuitError);
  559.         retvalue=TRUE;
  560.     }
  561.     if ( !env.hasColorQD)
  562.     {    ParamAString("\pUAE requires Color QuickDraw!");
  563.         DisplayError(kQuitError);
  564.         retvalue=TRUE;
  565.     }
  566.     if ( env.processor < 3)
  567.     {    ParamAString("\pUAE requires a 68020 or better processor to run!");
  568.         DisplayError(kQuitError);
  569.         retvalue=TRUE;
  570.     }
  571.     curDevice = GetMainDevice();
  572.     if ((*curDevice)->gdPMap == NULL || (*(*curDevice)->gdPMap)->pixelSize != 16)
  573.     {    if (HasDepth(curDevice,16,0,0) == 0)
  574.         {    ParamAString("\pUAE requires 16 bit color and your display doesn't support it!");
  575.             DisplayError(kQuitError);
  576.             retvalue=TRUE;
  577.         }
  578.         else
  579.         {
  580.         oldDepth=(*(*curDevice)->gdPMap)->pixelSize;
  581.         SetDepth(curDevice,16,0,0);
  582.         }
  583.     }
  584.     return(retvalue);
  585. }
  586.  
  587. // Shows up the standard error alert;
  588. int DisplayError(int ID)
  589. {    int    ret=0;
  590.  
  591.     InitCursor();
  592.     ret=Alert(ID,0);
  593.  
  594.     return (ret);
  595. }
  596.  
  597. // Parses a Pascal string for error display
  598. void ParamAString( ConstStr255Param theStr )
  599. {
  600.     ParamText(theStr, "\p", "\p", "\p");
  601. }
  602.